package cn.cj.erp.common.excel.excel;

import cn.cj.erp.common.excel.anno.Excel;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Method;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;

/**
 * excel日期处理工具
 *
 * @author jianchen
 */
@Slf4j
public class ExcelFieldHandler {
    public static final String SETTER_PREFIX = "set";

    public static final String GETTER_PREFIX = "get";

    private static final String[] PARSE_PATTERNS = {
        "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
        "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
        "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"
    };
    /**
     * 日期型字符串转化为日期 格式
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return DateUtil.parseByPatterns(str.toString(), PARSE_PATTERNS).getTime();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 格式化不同类型的日期对象
     *
     * @param format 日期格式
     * @param val        被格式化的日期对象
     * @return 格式化后的日期字符
     */
    public static String format(String format, Object val) {
        if (val == null) {
            return "";
        }
        if (val instanceof Date) {
            return DateUtil.format((Date) val, format);
        } else if (val instanceof LocalDateTime) {
            return DateUtil.format((LocalDateTime) val, format);
        } else if (val instanceof LocalDate) {
            LocalDateTime localDateTime = LocalDateTime.of((LocalDate) val,
                    LocalTime.of(0, 0, 0));
            return DateUtil.format(localDateTime, format);
        } else {
            return val.toString();
        }
    }

    /**
     * 获取对象的子列表方法
     *
     * @param name      名称
     * @param clazz 类对象
     * @return 子列表方法
     */
    public static Method getSubMethod(String name, Class<?> clazz) {
        Method method = null;
        try {
            method = clazz.getMethod(String.format("%s%s", GETTER_PREFIX, StrUtil.upperFirst(name)));
        } catch (Exception e) {
            log.error("获取对象异常{}", e.getMessage());
        }
        return method;
    }

    /**
     * 解析导出值 0=男,1=女,2=未知
     *
     * @param propertyValue 参数值
     * @param converterExp  翻译注解
     * @param separator     分隔符
     * @return 解析后值
     */
    public static String convertByExp(String propertyValue, String converterExp, String separator) {
        StringBuilder propertyString = new StringBuilder();
        String[] convertSource = converterExp.split(",");
        for (String item : convertSource) {
            String[] itemArray = item.split("=");
            if (StrUtil.containsAny(propertyValue, separator)) {
                for (String value : propertyValue.split(separator)) {
                    if (itemArray[0].equals(value)) {
                        propertyString.append(itemArray[1]).append(separator);
                        break;
                    }
                }
            } else {
                if (itemArray[0].equals(propertyValue)) {
                    return itemArray[1];
                }
            }
        }
        return StrUtil.strip(propertyString.toString(), "", separator);
    }

    /**
     * 反向解析值 男=0,女=1,未知=2
     *
     * @param propertyValue 参数值
     * @param converterExp  翻译注解
     * @param separator     分隔符
     * @return 解析后值
     */
    public static String reverseByExp(String propertyValue, String converterExp, String separator) {
        StringBuilder propertyString = new StringBuilder();
        String[] convertSource = converterExp.split(",");
        for (String item : convertSource) {
            String[] itemArray = item.split("=");
            if (StrUtil.containsAny(propertyValue, separator)) {
                for (String value : propertyValue.split(separator)) {
                    if (itemArray[1].equals(value)) {
                        propertyString.append(itemArray[0]).append(separator);
                        break;
                    }
                }
            } else {
                if (itemArray[1].equals(propertyValue)) {
                    return itemArray[0];
                }
            }
        }
        return StrUtil.strip(propertyString.toString(), "", separator);
    }

    /**
     * 数据处理器
     *
     * @param value 数据值
     * @param formatter 自定义数据格式化器
     * @return 处理结果
     */
    public static Object customFormat(Object value, Class<?> formatter, String[] args) {
        try {
            Object instance = formatter.newInstance();
            Method formatMethod = formatter.getMethod("format", Object.class, String[].class);
            value = formatMethod.invoke(instance, value, args);
        } catch (Exception e) {
            log.error("不能格式化数据 {}\n{} ", formatter, e.getMessage());
        }
        return value;
    }

    /**
     * 获取单元格标题样式key
     * @param attr Excel注解
     * @return key
     */
    public static String getHeadStyleKey(Excel attr) {
        return StrUtil.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor());
    }

    /**
     * 获取单元格数据样式key
     * @param attr Excel注解
     * @return key
     */
    public static String getDataStyleKey(Excel attr) {
        return StrUtil.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor());
    }
}